package org.hank.compose_yyzs.ui.paging

import androidx.compose.runtime.MutableState
import androidx.compose.runtime.State
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import androidx.paging.*
import com.orhanobut.logger.Logger
import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.launch
import org.hank.compose_yyzs.bean.PageWrapper
import org.hank.compose_yyzs.http.bean.HttpResult
import org.hank.compose_yyzs.http.bean.HttpWrapBean

fun <T : Any, K : Any> ViewModel.simplePager(
    isRequest: MutableStateFlow<Boolean>,
    config: AppPagingConfig = AppPagingConfig(),
    secondAction: suspend (list: MutableList<T>) -> HttpWrapBean<MutableList<K>>,
    secondMerge: suspend (callList: MutableList<T>, secondList: MutableList<K>) -> MutableList<T>,
    callAction: suspend (page: Int) -> HttpWrapBean<PageWrapper<T>>
): Flow<PagingData<T>> {
    return pager(config, 1) {
        val page = it.key ?: 1
        Logger.d("enter load $page")
        val response = try {
            HttpResult.Success(callAction.invoke(page))
        } catch (e: Exception) {
            HttpResult.Error(e)
        }
        if (page == 1)
            isRequest.value = false
        when (response) {
            is HttpResult.Success -> {
                val data = response.result
                val hasNotNext = (data.data.totalPage > data.data.currPage)
                Logger.d("hasNotNext ==$hasNotNext")

                if (!data.data.datas.isNullOrEmpty()) {
                    val responseSecond = try {
                        HttpResult.Success(secondAction.invoke(data.data.datas.toMutableList()))
                    } catch (e: Exception) {
                        HttpResult.Error(e)
                    }
                    when (responseSecond) {
                        is HttpResult.Success -> {
                            PagingSource.LoadResult.Page(
                                data = secondMerge.invoke(
                                    data.data.datas.toMutableList(),
                                    responseSecond.result.data
                                ),
                                prevKey = if (page > 1) page - 1 else null,
                                nextKey = if (hasNotNext) page + 1 else null
                            )
                        }

                        is HttpResult.Error -> {
                            PagingSource.LoadResult.Error(responseSecond.exception)
                        }
                    }
                } else {
                    PagingSource.LoadResult.Page(
                        data = emptyList(),
                        prevKey = if (page > 1) page - 1 else null,
                        nextKey = if (hasNotNext) page + 1 else null
                    )
                }
            }

            is HttpResult.Error -> {
                PagingSource.LoadResult.Error(response.exception)
            }
        }
    }
}

fun <T : Any> ViewModel.simplePager(
    isRefreshing: MutableStateFlow<Boolean>,
    config: AppPagingConfig = AppPagingConfig(),
    callAction: suspend (page: Int) -> HttpWrapBean<PageWrapper<T>>
): Flow<PagingData<T>> {
    return pager(config, 1) {
        val page = it.key ?: 1
        Logger.d("enter load $page")
        val response = try {
            HttpResult.Success(callAction.invoke(page))
        } catch (e: Exception) {
            HttpResult.Error(e)
        }
        if (page == 1) {
            isRefreshing.emit(false)
        }
        when (response) {
            is HttpResult.Success -> {
                val data = response.result
                val hasNotNext = (data.data.totalPage > data.data.currPage)
                Logger.d("hasNotNext ==$hasNotNext")
                PagingSource.LoadResult.Page(
                    data = data.data.datas,
                    prevKey = if (page > 1) page - 1 else null,
                    nextKey = if (hasNotNext) page + 1 else null
                )
            }

            is HttpResult.Error -> {
                PagingSource.LoadResult.Error(response.exception)
            }
        }
    }
}

fun <K : Any, V : Any> ViewModel.pager(
    config: AppPagingConfig = AppPagingConfig(),
    initialKey: K? = null,
    loadData: suspend (PagingSource.LoadParams<K>) -> PagingSource.LoadResult<K, V>
): Flow<PagingData<V>> {
    val baseConfig = PagingConfig(
        config.pageSize,
        initialLoadSize = config.initialLoadSize,
        prefetchDistance = config.prefetchDistance,
        maxSize = config.maxSize,
        enablePlaceholders = config.enablePlaceholders
    )
    return Pager(
        config = baseConfig,
        initialKey = initialKey
    ) {
        object : PagingSource<K, V>() {
            override suspend fun load(params: LoadParams<K>): LoadResult<K, V> {
                return loadData.invoke(params)
            }

            override fun getRefreshKey(state: PagingState<K, V>): K? {
                return initialKey
            }

        }
    }.flow.cachedIn(viewModelScope)
}